/**
 * Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package com.example.mcp;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import dev.langchain4j.service.AiServices;
import dev.langchain4j.service.tool.ToolProvider;
import dev.langchain4j.mcp.McpToolProvider;
import dev.langchain4j.mcp.client.DefaultMcpClient;
import dev.langchain4j.mcp.client.McpClient;
import dev.langchain4j.mcp.client.transport.McpTransport;
import dev.langchain4j.mcp.client.transport.http.HttpMcpTransport;
import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.openai.spring.AutoConfig;

@Configuration
@AutoConfigureAfter(AutoConfig.class)
@ConditionalOnProperty(prefix = "langchain4j.mcp-sse-server", name = "enabled", havingValue = "true", matchIfMissing = false)
@EnableConfigurationProperties(GiteeClientProperties.class)
public class GiteeClientConfiguration {

    @Autowired
    private GiteeClientProperties properties;

    /**
     * 注册McpTransport
     * 
     * @return {@link HttpMcpTransport}
     */
    @Bean
    @ConditionalOnMissingBean
    public McpTransport mcpTransport() {
        return new HttpMcpTransport.Builder()
                .sseUrl(properties.getUrl())
                .logRequests(properties.getLogRequests())
                .logResponses(properties.getLogResponses())
                .build();
    }

    /**
     * 注册McpClient
     * 
     * @param mcpTransport {@link McpTransport}
     * @return {@link DefaultMcpClient}
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnBean(McpTransport.class)
    public McpClient mcpClient(McpTransport mcpTransport) {
        return new DefaultMcpClient.Builder()
                .transport(mcpTransport)
                .build();
    }

    /**
     * 注册ToolProvider
     * 
     * @param mcpClient {@link McpClient}
     * @return {@link McpToolProvider}
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnBean(McpClient.class)
    public ToolProvider toolProvider(McpClient mcpClient) {
        return McpToolProvider.builder()
                .mcpClients(mcpClient)
                .build();
    }

    /**
     * 注册GiteeClientService
     * 
     * @param toolProvider {@link ToolProvider}
     * @param openAiChatModel {@link OpenAiChatModel}
     * @return
     */
    @Bean
    @ConditionalOnMissingBean
    public GiteeClientService giteeClientService(ToolProvider toolProvider, OpenAiChatModel openAiChatModel) {
        return AiServices.builder(GiteeClientService.class)
                .chatLanguageModel(openAiChatModel)
                .toolProvider(toolProvider)
                .build();
    }

    @Bean
    @ConditionalOnMissingBean
    public FederatedQueryEngineService federatedQueryEngineService(ToolProvider toolProvider, OpenAiChatModel openAiChatModel) {
        return AiServices.builder(FederatedQueryEngineService.class)
               .chatLanguageModel(openAiChatModel)
               .toolProvider(toolProvider)
               .build();
    }
}
